home *** CD-ROM | disk | FTP | other *** search
/ Amiga News 95 / Amiga News 95.iso / dpat / dpat50 / cprg / decompc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-23  |  10.9 KB  |  334 lines

  1. /*************************************************************************/
  2. /*                                                                       */
  3. /*              DECOMPC.C Compression de fichiers source C.              */
  4. /*              V1.00 FREEWARE Christian BRUNON 20-08-1993               */
  5. /*                                                                       */
  6. /*             +-----------------------------------------+               */
  7. /*             | Logiciel placé dans le domaine FREEWARE |               */
  8. /*             +-----------------------------------------+               */
  9. /* L'utilisation et la diffusion de ce programme, des fichiers sources   */
  10. /* et de la documentation sont entièrement libres.                       */
  11. /*                                                                       */
  12. /*                           Christian BRUNON                            */
  13. /*                        30 Rue Georges Brassens                        */
  14. /*                      43140 LA SEAUVE SUR SEMENE                       */
  15. /*                                FRANCE                                 */
  16. /*                                                                       */
  17. /*            Fichier source Lattice C AmigaDOS Version 5.04             */
  18. /*                                                                       */
  19. /*************************************************************************/
  20.  
  21. /* Fichier INCLUDE */
  22. #include "CPRG:CompC.H"
  23.  
  24. static int Car,     /* Caractère lu dans le fichier           */
  25.            CarPrec; /* Caractère précédent lu dans le fichier */
  26.  
  27. static UBYTE ListeMots[MaxMots][MaxLongMot];
  28.  
  29. const UBYTE *ListeErreurs[] =
  30.      {
  31.       "\n",
  32.       "Utilisation : DeCompC [-DEST] Fichier1[.K] [-DEST] [Fichier2[.K]] [...]\n",
  33.       "\aFichier inexistant\n",
  34.       "\aErreur en création\n",
  35.       "\aErreur en écriture\n",
  36.       "\aErreur en lecture\n",
  37.       "\aPas assez de mémoire\n",
  38.       "\a***BREAK\n"
  39.      };
  40.  
  41. extern int (*_ONBREAK)();
  42.  
  43. /**************************************************************************/
  44.  
  45. int CXBRK()
  46. {
  47.  CodeErreur=BreakError;
  48.  
  49.  return(0);
  50. }
  51.  
  52. /**************************************************************************/
  53.  
  54. void InsererMot()
  55. {
  56.  /* VARIABLES LOCALES */
  57.  register UBYTE Pos=0;
  58.  
  59.  Car=fgetc(FIn);
  60.  
  61.  /* Chargement dans la liste et écriture dans le fichier décompressé du
  62.   * nouveau mot.
  63.   * Le nouveau mot se termine dans le fichier lu, par la marque de nouveau
  64.   * mot NouveauMot='\0'
  65.   */
  66.  while((FIn->_flag)==_IOREAD && CodeErreur==0 && Car!=NouveauMot)
  67.       {
  68.        if(fputc(ListeMots[NbMots][Pos++]=Car,FOut)==EOF) CodeErreur=WriteError;
  69.        Car=fgetc(FIn);
  70.       }
  71.  
  72.  /* Erreur en lecture ? */
  73.  if(((FIn->_flag)!=_IOREAD || Car) && CodeErreur==0) CodeErreur=ReadError;
  74.  
  75.  ListeMots[NbMots][Pos]=0;
  76.  
  77.  NbMots++;
  78. }
  79.  
  80. /**************************************************************************/
  81.  
  82. UBYTE DeCompresserFichier()
  83. {
  84.  /* Le fichier est-il vide ?                                     */
  85.  /* if(((Car=fgetc(FIn))==EOF) && (feof(FIn)))                   */
  86.  /*        {                                                     */
  87.  /*         printf("Fichier vide.\n");                           */
  88.  /*         return(1);                                           */
  89.  /*        }                                                     */
  90.  /*                                                              */
  91.  /* Fichier non vide : on replace le caractère lu dans le buffer */
  92.  /* ungetc(Car,FIn);                                             */
  93.  
  94.  printf("Création du fichier %s  ",NomFicOut);
  95.  
  96.  if((FOut=fopen(NomFicOut,"wb"))==NULL) return(CreateError);
  97.  
  98.  CarPrec='\n';
  99.  Car=fgetc(FIn);
  100.  
  101.  ComptLignes=NbMots=0;
  102.  
  103.  while(FIn->_flag==_IOREAD && CodeErreur==0)
  104.       {
  105.        /* Code d'une ligne vide */
  106.        if(Car==LigneVide){
  107.                           if(fputc('\n',FOut)==EOF) CodeErreur=WriteError;
  108.                          }
  109.        else{
  110.             /* Ecriture des espaces initiaux, Car=Nb espaces initiaux */
  111.             while(Car && CodeErreur==0)
  112.                  {
  113.                   if(fputc(' ',FOut)==EOF) CodeErreur=WriteError;
  114.                   Car--;
  115.                  }
  116.  
  117.             /* Lecture du premier caractère ou code */
  118.             Car=fgetc(FIn);
  119.  
  120.             /* Lecture du restant de la ligne compressée */
  121.             while(FIn->_flag==_IOREAD && Car!='\n' && CodeErreur==0)
  122.                  {
  123.                   /* Code d'un nouveau mot */
  124.                   if(Car==NouveauMot) InsererMot();
  125.  
  126.                   /* Code d'un mot déjà lu */
  127.                   else if(Car==MotExistant)
  128.                         {
  129.                          /* Lecture du code du mot */
  130.                          CodeMot=fgetc(FIn)|(fgetc(FIn)<<8);
  131.  
  132.                          /* Ecriture du mot */
  133.                          if(fputs(ListeMots[CodeMot],FOut)) CodeErreur=WriteError;
  134.                         }
  135.  
  136.                   /* Code d'un début de commentaire */
  137.                   else if(Car==Commentaire1On)
  138.                         {
  139.                          if(fputs("/*",FOut)) CodeErreur=WriteError;
  140.                         }
  141.  
  142.                   /* Code d'une fin de commentaire */
  143.                   else if(Car==Commentaire1Off)
  144.                         {
  145.                          if(fputs("*/",FOut)) CodeErreur=WriteError;
  146.                         }
  147.  
  148.                   /* Code d'un début de commentaire + espace */
  149.                   else if(Car==Commentaire2On)
  150.                         {
  151.                          if(fputs("/* ",FOut)) CodeErreur=WriteError;
  152.                         }
  153.  
  154.                   /* Code d'un espace + fin de commentaire */
  155.                   else if(Car==Commentaire2Off)
  156.                         {
  157.                          if(fputs(" */",FOut)) CodeErreur=WriteError;
  158.                         }
  159.  
  160.                   /* Caractère quelconque */
  161.                   else if(fputc(Car,FOut)==EOF) CodeErreur=WriteError;
  162.  
  163.                   Car=fgetc(FIn);
  164.                  }
  165.  
  166.             /* Saut de fin de ligne */
  167.             if(fputc('\n',FOut)==EOF) CodeErreur=WriteError;
  168.  
  169.             /* Affichage du nombre d'octets lus */
  170.             if(!ComptLignes++) printf("%7u\b\b\b\b\b\b\b",ftell(FIn));
  171.  
  172.             ComptLignes%=10;
  173.            }
  174.  
  175.        Car=fgetc(FIn);
  176.       }
  177.  
  178.  if(CarPrec!='\n' && CodeErreur==0) if(fputc('\n',FOut)==EOF) CodeErreur=WriteError;
  179.  
  180.  /* Erreur en lecture ou fin normal de fichier ? */
  181.  if(FIn->_flag!=(_IOREAD|_IOEOF)) CodeErreur=ReadError;
  182.  
  183.  return(CodeErreur);
  184. }
  185.  
  186. /**************************************************************************/
  187.  
  188. UBYTE main(int argc,char *argv[])
  189. {
  190.  /* Déclarations et fonctions de Exec.Library */
  191.  extern struct ExecBase *SysBase;
  192.  extern void *AllocMem(long,long);
  193.  extern void FreeMem(void *,long);
  194.  #pragma syscall AllocMem c6 1002
  195.  #pragma syscall FreeMem d2 902
  196.  
  197.  register struct FileInfoBlock *PtrFIB;
  198.  
  199.  /* Déclarations de variables externes de la DOS.Library */
  200.  extern struct DosLibrary *DOSBase;
  201.  extern BPTR CreateDir(char *);
  202.  extern long DeleteFile(char *);
  203.  extern long SetProtection(char *, ULONG);
  204.  extern LONG SetComment(char *, char *);
  205.  extern LONG Examine(BPTR, struct FileInfoBlock *);
  206.  extern BPTR Lock(char *, LONG);
  207.  extern void UnLock(BPTR);
  208.  #pragma libcall DOSBase CreateDir 78 101
  209.  #pragma libcall DOSBase DeleteFile 48 101
  210.  #pragma libcall DOSBase SetProtection ba 2102
  211.  #pragma libcall DOSBase SetComment b4 2102
  212.  #pragma libcall DOSBase Examine 66 2102
  213.  #pragma libcall DOSBase Lock 54 2102
  214.  #pragma libcall DOSBase UnLock 5a 101
  215.  
  216.  /* VARIABLES LOCALES */
  217.  register UBYTE NuArg,
  218.                 FlagNewDir=0,  /* Changer le répertoire de destination ? */
  219.                 CreerChemin=0, /* Créer le nouveau répertoire ?          */
  220.                 NewChemin[80],
  221.                 FileName[108],
  222.                 Commentaire[80];
  223.  
  224.  register BPTR Clef; /* Paramètre utilisé pour Examine() et CreateDir() */
  225.  
  226.  register ULONG Protection;
  227.  
  228.  /*********************** DEBUT DU CODE DE main() **************************/
  229.  
  230.  _ONBREAK=CXBRK;
  231.  
  232.  printf("DeCompC V1.00 FREEWARE Christian BRUNON 20-08-1993\n");
  233.  
  234.  /* Pas de paramètre ou paramètre ? */
  235.  if(argc==1 || (argc==2 && argv[1][0]=='?' && argv[1][1]=='\0'))
  236.    {
  237.     printf("%s",ListeErreurs[1]);
  238.     return(1);
  239.    }
  240.  
  241.  if((PtrFIB=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0L))==NULL)
  242.    {
  243.     printf("%s",ListeErreurs[MemoryError]);
  244.     return(MemoryError);
  245.    }
  246.  
  247.  for(NuArg=1;NuArg<argc;NuArg++)
  248.  if(argv[NuArg][0]=='-')
  249.      /* Le paramètre lu est un nouveau chemin */
  250.      {
  251.       FlagNewDir=(UBYTE)1;
  252.       strcpy(NewChemin,&argv[NuArg][1]);
  253.  
  254.       if(NewChemin[0]) CreerChemin=LastChar(NewChemin)!=':' && LastChar(NewChemin)!='/';
  255.  
  256.       if(CreerChemin && NewChemin[0])
  257.         {
  258.          if(Clef=CreateDir(NewChemin)) UnLock(Clef);
  259.  
  260.          strcat(NewChemin,"/");
  261.         }
  262.      }
  263.  /* Le paramètre lu est un fichier à décompresser */
  264.  else{
  265.       CodeErreur=0;
  266.  
  267.       /* Détermination du nom du fichier à décompresser.
  268.        * Rajout de l'extension ".K" si nécessaire.
  269.        */
  270.       strcpy(NomFicIn,argv[NuArg]);
  271.       if(NomFicIn[strlen(NomFicIn)-2]!='.' || UpChar(LastChar(NomFicIn))!='K') strcat(NomFicIn,".K");
  272.  
  273.       if(Clef=Lock(NomFicIn,ACCESS_READ))
  274.           {
  275.            /* Test existence et test type = fichier */
  276.            if(Examine(Clef,PtrFIB) && PtrFIB->fib_DirEntryType<0)
  277.                {
  278.                 strcpy(FileName,PtrFIB->fib_FileName);
  279.                 LongFicIn=PtrFIB->fib_Size;
  280.                 Protection=(ULONG)PtrFIB->fib_Protection;
  281.                 strcpy(Commentaire,PtrFIB->fib_Comment);
  282.                }
  283.            else CodeErreur=FileOpenReadError;
  284.  
  285.            UnLock(Clef);
  286.           }
  287.       else CodeErreur=FileOpenReadError;
  288.  
  289.       if(CodeErreur){
  290.                      printf("%s %s",NomFicIn,ListeErreurs[CodeErreur]);
  291.                      continue;
  292.                     }
  293.  
  294.       /* Détermination du nom du fichier décompressé */
  295.       if(FlagNewDir)
  296.           {
  297.            strcpy(NomFicOut,NewChemin);
  298.            strcat(NomFicOut,FileName);
  299.           }
  300.       else strcpy(NomFicOut,NomFicIn);
  301.  
  302.       /* Annulation des 2 derniers caractères qui sont ".K" */
  303.       NomFicOut[strlen(NomFicOut)-2]='\0';
  304.  
  305.       printf("Ouverture du fichier %s\r",NomFicIn);
  306.  
  307.       if(FIn=fopen(NomFicIn,"rb"))
  308.         {
  309.          CodeErreur=DeCompresserFichier();
  310.  
  311.          /* Affichage du code d'erreur */
  312.          if(CodeErreur) printf("%s",ListeErreurs[CodeErreur]);
  313.          else printf("%7u\n",ftell(FOut));
  314.  
  315.          if(FOut) fclose(FOut);
  316.          if(FIn)  fclose(FIn);
  317.  
  318.          if(CodeErreur) DeleteFile(NomFicOut);
  319.          else /* Recopie des bits d'attributs de fichier et du commentaire */
  320.              {
  321.               SetProtection(NomFicOut,Protection);
  322.               SetComment(NomFicOut,Commentaire);
  323.              }
  324.         }
  325.       /* Fichier inexistant ou illisible */
  326.       else printf("%s",ListeErreurs[CodeErreur=FileOpenReadError]);
  327.      }
  328.  
  329.  if(PtrFIB) FreeMem(PtrFIB,sizeof(struct FileInfoBlock));
  330.  
  331.  /* Renvoie le code d'erreur du dernier fichier décompressé */
  332.  return(CodeErreur);
  333. }
  334.